/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin			*/
/*	Project:	GlbCloud			*/
/*	Author:		gong_libin			*/
/*	Date:		2012_02_20			*/
/*	File:		MrUdp.cpp			*/
/********************************************************/

#include "MrUdp.h"

CMrUdp::CMrUdp()
{
	memset(&m_stAddr, '\0', sizeof(struct sockaddr_in));
}

CMrUdp::~CMrUdp()
{
}

void* CMrUdp::MrUdpGetAddr()
{
	return (void*)&m_stAddr;
}

void CMrUdp::MrUdpReset()
{
	memset(&m_stAddr, '\0', sizeof(struct sockaddr_in));

	return;
}

void CMrUdp::MrUdpSetAddr(void* pAddr)
{
	memcpy(&m_stAddr, pAddr, sizeof(struct sockaddr_in));

	return;
}

void CMrUdp::MrUdpSetAddr(char* pszUrl)
{
	char* pszPort = NULL;

	if (NULL != (pszPort = CMrNet::MrNetUrl(pszUrl))) {
		m_stAddr.sin_addr.s_addr = inet_addr(pszUrl);
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_family = AF_INET;
	}

	return;
}

int CMrUdp::MrUdpConnect(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = MR_SUCCESS;

	if (NULL != (pszPort = CMrNet::MrNetUrl(pszUrl))) {
		iReturn = MrUdpConnect(pszUrl, pszPort);
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}

int CMrUdp::MrUdpConnect(struct sockaddr_in* pstAddr)
{
	int iReturn = MR_SUCCESS;
	struct sockaddr_in* pstCur = NULL;

	if (NULL != pstAddr) {
		pstCur = pstAddr;
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}
	else {
		pstCur = &m_stAddr;
	}

	if (MR_SUCCESS == CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
		CMrNet::MrNetSetTimeOut(MR_TIMEOUT, 0);
		if (connect(CMrNet::m_iSocket, (struct sockaddr*)pstCur, sizeof(struct sockaddr_in)) < 0) {
			MR_ERROR("%s\n", strerror(errno));
			iReturn = MR_FAILURE;
			CMrNet::MrNetClose();
		}
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}

int CMrUdp::MrUdpConnect(char* pszAddr, char* pszPort)
{
	int iReturn = MR_SUCCESS;

	m_stAddr.sin_addr.s_addr = inet_addr(pszAddr);
	m_stAddr.sin_port = htons(atoi(pszPort));
	m_stAddr.sin_family = AF_INET;

	if (MR_SUCCESS == CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
		CMrNet::MrNetSetTimeOut(MR_TIMEOUT, 0);
		if (connect(CMrNet::m_iSocket, (struct sockaddr*)&m_stAddr, sizeof(struct sockaddr_in)) < 0) {
			MR_ERROR("%s\n", strerror(errno));
			iReturn = MR_FAILURE;
			CMrNet::MrNetClose();
		}
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}

int CMrUdp::MrUdpRead(UCHAR* puszPacket, UINT uiLength)
{
	return read(CMrNet::m_iSocket, puszPacket, uiLength);
}

int CMrUdp::MrUdpWrite(UCHAR* puszPacket, UINT uiLength)
{
	return write(CMrNet::m_iSocket, puszPacket, uiLength);
}

int CMrUdp::MrNetInitSend(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = MR_SUCCESS;

	if (NULL != (pszPort = CMrNet::MrNetUrl(pszUrl))) {
		iReturn = MrNetInitSend(pszUrl, pszPort);
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}

int CMrUdp::MrNetInitRecv(char* pszUrl)
{
	char* pszPort = NULL;
	int iReturn = MR_SUCCESS;

	if (NULL != (pszPort = CMrNet::MrNetUrl(pszUrl))) {
		iReturn = MrNetInitRecv(pszUrl, pszPort);
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}

int CMrUdp::MrNetInitSend(struct sockaddr_in* pstAddr)
{
	if (NULL != pstAddr) {
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}

	if (MR_SUCCESS != CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}

int CMrUdp::MrNetInitRecv(struct sockaddr_in* pstAddr)
{
	struct sockaddr_in* pstCur = NULL;

	if (NULL != pstAddr) {
		pstCur = pstAddr;
		memcpy(&m_stAddr, pstAddr, sizeof(struct sockaddr_in));
	}
	else {
		pstCur = &m_stAddr;
	}

	if (MR_SUCCESS == CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
		if (bind(CMrNet::m_iSocket, (struct sockaddr*)pstCur, sizeof(struct sockaddr_in)) < 0) {
			MR_ERROR("%s\n", strerror(errno));
			CMrNet::MrNetClose();
			return MR_FAILURE;
		}
	}
	else {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}

int CMrUdp::MrNetInitSend(char* pszAddr, char* pszPort)
{
	if (NULL != pszAddr && NULL != pszPort) {
		m_stAddr.sin_family = AF_INET;
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_addr.s_addr = inet_addr(pszAddr);

		if (MR_SUCCESS != CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
			return MR_FAILURE;
		}
	}
	else {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}

int CMrUdp::MrNetInitRecv(char* pszAddr, char* pszPort)
{
	if (NULL != pszPort) {
		m_stAddr.sin_family = AF_INET;
		m_stAddr.sin_port = htons(atoi(pszPort));
		m_stAddr.sin_addr.s_addr = htonl(INADDR_ANY);

		if (MR_SUCCESS == CMrNet::MrNetOpen(MR_SOCK_DGRAM)) {
			if (bind(CMrNet::m_iSocket, (struct sockaddr*)&m_stAddr, sizeof(struct sockaddr_in)) < 0) {
				MR_ERROR("%s\n", strerror(errno));
				CMrNet::MrNetClose();
				return MR_FAILURE;
			}
		}
		else {
			return MR_FAILURE;
		}
	}
	else {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}

int CMrUdp::MrNetSend(UCHAR* puszPacket, int iLength)
{
	return sendto(CMrNet::m_iSocket, puszPacket, iLength, 0, (struct sockaddr*)&m_stAddr, sizeof(struct sockaddr_in));
}

int CMrUdp::MrNetRecv(UCHAR* puszPacket, int iLength)
{
	int iUdp = sizeof(struct sockaddr_in);

	return recvfrom(CMrNet::m_iSocket, puszPacket, iLength, 0, (struct sockaddr*)&m_stAddr, (socklen_t*)&iUdp);
}

int CMrUdp::MrNetSendAll(UCHAR* puszPacket, int iLength)
{
	int iCount = 0;
	int iTotal = 0;

	while (iTotal < iLength) {
		if ((iCount = MrNetSend(puszPacket + iTotal, iLength - iTotal)) > 0) {
			iTotal += iCount;
		}
		else {
			MR_ERROR("%s\n", strerror(errno));
			break;
		}
	}

	return iTotal;

}

int CMrUdp::MrNetRecvAll(UCHAR* puszPacket, int iLength)
{
	int iCount = 0;
	int iTotal = 0;

	while (iTotal < iLength) {
		if ((iCount = MrNetRecv(puszPacket + iTotal, iLength - iTotal)) > 0) {
			iTotal += iCount;
		}
		else {
			MR_ERROR("%s\n", strerror(errno));
			break;
		}
	}

	return iTotal;
}
